package org.goat.caprabank.client;

import org.goat.caprabank.shared.entity.BankTransaction;
import org.goat.caprabank.shared.entity.User;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.RowFormatter;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class AccountDetailsPanel extends Composite {
	interface AccountDetailsPanelUiBinder extends UiBinder<Widget, AccountDetailsPanel> {
	}

	private static AccountDetailsPanelUiBinder uiBinder = GWT.create(AccountDetailsPanelUiBinder.class);

	private final Caprabank caprabank;

	public AccountDetailsPanel(Caprabank caprabank, User user) {
		initWidget(uiBinder.createAndBindUi(this));
		this.caprabank = caprabank;
		greeting.setText("Welcome, " + user.firstName + " " + user.lastName + "!");
		accountNum.setText(String.valueOf(user.accountNum));
		balance.setText(formatAmount(user.balance) + " CapraCoins");
		if (user.transactions != null) {
			DateTimeFormat dateFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_SHORT);
			transactionsGrid.resizeRows(user.transactions.size() + 1);
			RowFormatter rowFormatter = transactionsGrid.getRowFormatter();
			int row = 1;
			for (BankTransaction transaction : user.transactions) {
				boolean isOutgoing = transaction.fromAccount == user.accountNum;
				transactionsGrid.setText(row, 0, String.valueOf(transaction.transactionId));
				transactionsGrid.setText(row, 1, dateFormat.format(transaction.timestamp));
				transactionsGrid.setText(row, 2, formatAccountNum(transaction.fromAccount, user));
				transactionsGrid.setText(row, 3, formatAccountNum(transaction.toAccount, user));
				transactionsGrid.setText(row, 4, (isOutgoing ? "- " : "+ ") + formatAmount(transaction.amount));
				transactionsGrid.setText(row, 5, transaction.comment);
				rowFormatter.addStyleName(row, isOutgoing ? "transactionsTableOutgoingTransactionRow" : "transactionsTableIncomingTransactionRow");
				row++;
			}
		}
		CellFormatter cellFormatter = transactionsGrid.getCellFormatter();
		for (int row = 0; row < transactionsGrid.getRowCount(); row++) {
			for (int cell = 0; cell < transactionsGrid.getCellCount(row); cell++) {
				cellFormatter.addStyleName(row, cell, "transactionsTableCell");
			}
		}
	}

	@UiField
	Label greeting;

	@UiField
	Label accountNum;

	@UiField
	Label balance;

	@UiField
	Grid transactionsGrid;

	@UiHandler("buyButton")
	void onClickBuy(ClickEvent e) {
		new ErrorDialog().showMessage("This operation is not supported in your country.");
	}

	@UiHandler("transferButton")
	void onClickTransfer(ClickEvent e) {
		caprabank.showTransferPage();
	}

	@UiHandler("logoutButton")
	void onClickLogout(ClickEvent e) {
		caprabank.bankService.logout(new DefaultCallback<Void>());
		caprabank.showLoginPage();
	}

	private String formatAmount(long amount) {
		return NumberFormat.getFormat("0.00").format((double) amount / 100);
	}

	private String formatAccountNum(long accountNum, User user) {
		return accountNum + (accountNum == user.accountNum ? " (this account)" : "");
	}
}
